#include "RuleObject.h"

RuleObject::RuleObject()
  : type_(NullType)
  , required_(true)
  , element_type_(NullType) {

}

RuleObject::RuleObject(RuleType type, bool required, RuleType element_type)
  : type_(type)
  , required_(required)
  , element_type_(element_type) {

}

RuleObject::~RuleObject() {

}

RuleObject::Ptr RuleObject::CreateBasicRule(
  RuleType type, bool required /*= true*/) {
  assert(type != NullType);
  assert(type != ArrayType);
  assert(type != ObjectType);
  RuleObject::Ptr rule(new RuleObject(type, required, NullType));
  return rule;
}

RuleObject::Ptr RuleObject::CreateBasicArrayRule(
  RuleType element_type, bool required /*= true*/) {
  assert(element_type != NullType);
  assert(element_type != ArrayType);
  assert(element_type != ObjectType);
  RuleObject::Ptr rule(new RuleObject(ArrayType, required, element_type));
  return rule;
}

RuleObject::Ptr RuleObject::CreateObjectRule(bool required /*= true*/) {
  RuleObject::Ptr rule(new RuleObject(ObjectType, required, NullType));
  return rule;
}

RuleObject::Ptr RuleObject::CreateObjectArrayRule(bool required /*= true*/) {
  RuleObject::Ptr rule(new RuleObject(ArrayType, required, ObjectType));
  return rule;
}

void RuleObject::AddBasicRule(std::string name, RuleType type, bool required) {
  assert(type_ == ObjectType ||
         (type_ == ArrayType && element_type_ == ObjectType));

  assert(type != NullType);
  assert(type != ArrayType);
  assert(type != ObjectType);

  RuleObject::Ptr rule(new RuleObject(type, required, NullType));
  rule_map_[name] = rule;
}

void RuleObject::AddBasicArrayRule(
  std::string name, bool required, RuleType element_type) {
  assert(type_ == ObjectType ||
         (type_ == ArrayType && element_type_ == ObjectType));

  assert(element_type != NullType);
  assert(element_type != ArrayType);
  assert(element_type != ObjectType);

  RuleObject::Ptr rule(new RuleObject(ArrayType, required, element_type));
  rule_map_[name] = rule;
}

RuleObject::Ptr RuleObject::AddObjectRule(std::string name, bool required) {
  assert(type_ == ObjectType ||
         (type_ == ArrayType && element_type_ == ObjectType));

  RuleObject::Ptr rule(new RuleObject(ObjectType, required, NullType));
  rule_map_[name] = rule;
  return rule;
}

RuleObject::Ptr RuleObject::AddObjectArrayRule(std::string name, bool required) {
  assert(type_ == ObjectType ||
         (type_ == ArrayType && element_type_ == ObjectType));

  RuleObject::Ptr rule(new RuleObject(ArrayType, required, ObjectType));
  rule_map_[name] = rule;
  return rule;
}
